#include <tipos.h>
#include <i386.h>
#include <string.h>

char toUpper(char c) {
	if (c >= 97 && c <= 122)
		return (c - 32);
	else 
		return c;
}


sint_32 strcmp(const char* p, const char* q) {
	for (; *p && *q && *p==*q; p++,q++);
	return *p?(*q?(sint_32)*p-(sint_32)*q:1):*q?-1:0;
}

/*
static sint_32 strncmp(const char* p, const char* q, uint_32 n) {
	for (; n && *p && *q && *p==*q; p++,q++,n--);
	return n?(*p?(*q?(sint_32)*p-(sint_32)*q:1):*q?-1:0):0;
}
*/

int
strncmp(const char *str1, const char *str2, uint_32 n) {
	int i;
	for (i = 0; i < n; i++) {
		if (str1[i] < str2[i]) 
			return -1;
		if (str1[i] > str2[i]) 
			return 1;
	}
	return 0;
}

char *strcpy(char *dest, const char *src) {
	unsigned i;
	for (i=0; src[i] != '\0'; ++i)
		dest[i] = src[i];
	dest[i] = '\0';
	return dest;
}

int 
strlen(const char *string) {
	const char *s;

	s = string;
	while (*s)
		s++;
	return s - string;
}

char *
strrev(char *str) {
	char *p1, *p2;

	if (!str || !*str)
		return str;

	for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
		*p1 ^= *p2;
		*p2 ^= *p1;
		*p1 ^= *p2;
	}

	return str;
}

char *
itoa(int m, char *s, int b) {
	static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
	int i=0, sign=0;
    
	uint_32 n = m;
	if (b!=16 && (sign = (m < 0)))
		n = -m;

	do {
		s[i++] = digits[n % b];
	} while ((n /= b) > 0);

	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';

	return strrev(s);
}

void *
memset(void *s, int c, uint_32 n)
{
	char * r = s;
	while ( n!=0 )
	{
		*r = c;
		r++;
		n--;
	}
	return s;
}

void *
memcpy(void *dest, const void *src, uint_32 n)
{
	char * d = dest;
	const char * s = src;
	uint_32 i;
	for ( i = 0; i < n; i++ )
		d[i] = s[i];
	return dest;
}

int
sprintf_internal(char * buffer_init, char * format, uint_32 * stack)
{
	char * buffer = buffer_init;
	char *pchar;
	
	for(pchar = format; *pchar != '\0'; pchar++) {
		
		if (*pchar == '%') {
			pchar++;
			switch (*pchar) {
				case 'd':
					itoa(*stack, buffer, 10);
					buffer += strlen(buffer);
					break;
				case 'x':
					itoa(*stack, buffer, 16);
					buffer += strlen(buffer);
					break;
				case 'b':
					itoa(*stack, buffer, 2);
					buffer += strlen(buffer);
					break;
				case 's':
					strcpy(buffer, (char *) *stack);
					buffer += strlen(buffer);
					break;
				case '%':
					*buffer = '%';
					stack--;
					buffer++;
					break;
			}
			stack++;
			continue;
		}
		
		*buffer = *pchar;
		buffer++;
	}

	*buffer = '\0';
	return (buffer - buffer_init);
}

int sprintf(char *str, char* format, ...) {
	uint_32 *param;

	param = (uint_32 *) rebp();
	param += 6;
	
	return sprintf_internal(str, format, param);
}
